mod user;
mod role;

use axum::{
    Router,
};
use sqlx::{sqlite::SqlitePool};
use std::sync::Arc;
use std::net::SocketAddr;

// 数据库连接池类型
type Db = Arc<SqlitePool>;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化数据库连接池
    let pool = SqlitePool::connect("sqlite::memory:").await?;
    
    // 创建用户表 - 预编译SQL
    let create_users_table_sql = "CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        sex TEXT NOT NULL
    )";
    sqlx::query(create_users_table_sql)
        .execute(&pool)
        .await?;

    // 创建角色表 - 预编译SQL
    let create_roles_table_sql = "CREATE TABLE IF NOT EXISTS roles (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        description TEXT NOT NULL
    )";
    sqlx::query(create_roles_table_sql)
        .execute(&pool)
        .await?;

    // 初始化一些测试数据 - 预编译SQL
    sqlx::query("INSERT INTO users (name, sex) VALUES (?, ?)")
        .bind("Alice")
        .bind("Female")
        .execute(&pool)
        .await?;
        
    sqlx::query("INSERT INTO users (name, sex) VALUES (?, ?)")
        .bind("Bob")
        .bind("Male")
        .execute(&pool)
        .await?;
        
    sqlx::query("INSERT INTO roles (name, description) VALUES (?, ?)")
        .bind("Admin")
        .bind("Administrator role with full access")
        .execute(&pool)
        .await?;
        
    sqlx::query("INSERT INTO roles (name, description) VALUES (?, ?)")
        .bind("User")
        .bind("Standard user role with limited access")
        .execute(&pool)
        .await?;

    // 将连接池包装在 Arc 中以便在线程间共享
    let db = Arc::new(pool);

    // 创建路由
    let app = Router::new()
        .merge(user::routes::user_routes())
        .merge(role::routes::role_routes())
        .with_state(db);

    // 启动服务器
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    println!("Server running on http://{}", addr);
    println!("Now using prepared statements and named parameters like JDBC PreparedStatement!");
    println!("Users and Roles API available:");
    println!("  Users CRUD:");
    println!("    GET    /users      - List all users");
    println!("    POST   /users      - Create a new user");
    println!("    GET    /users/:id  - Get a user by ID");
    println!("    PUT    /users/:id  - Update a user by ID");
    println!("    DELETE /users/:id  - Delete a user by ID");
    println!("  Roles CRUD:");
    println!("    GET    /roles      - List all roles");
    println!("    POST   /roles      - Create a new role");
    println!("    GET    /roles/:id  - Get a role by ID");
    println!("    PUT    /roles/:id  - Update a role by ID");
    println!("    DELETE /roles/:id  - Delete a role by ID");
    
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await?;
    
    Ok(())
}